﻿using System.Reflection;

namespace XYS.Core.Util.Helper
{
    /// <summary>
    /// 
    /// </summary>
    public partial class AssemblyHelper
    {
        private static List<Type> AssemblyTypes = new();


        /// <summary>
        /// 增加 程序集
        /// </summary>
        /// <param name="assemblies"></param>
        /// <returns></returns>
        public static List<Type> Add(params Assembly[] assemblies)
        {
            var types = (assemblies?.SelectMany(a => a.GetTypes()) ?? new List<Type>()).Where(e => !AssemblyTypes.Any(t => t.FullName == e.FullName)).ToList();
            if (types.Count > 0)
                AssemblyTypes.AddRange(types);
            return AssemblyTypes;
        }

        /// <summary>
        /// 获取程序集内的Types
        /// </summary>
        /// <param name="assemblies"></param>
        /// <returns></returns>
        public static List<Type> GetAssemblyTypes(params Assembly[] assemblies)
        {
            if (AssemblyTypes != null && AssemblyTypes.Count > 0) { return AssemblyTypes; }

            AssemblyTypes = new List<Type>();

            //获取 调用当前方法的方法所在的程序集 的公共类型
            var callingTypes = Assembly.GetCallingAssembly().GetExportedTypes();
            AssemblyTypes.AddRange(callingTypes);

            //获取 当前方法所在的程序集 的公共类型
            var executingTypes = Assembly.GetExecutingAssembly().GetExportedTypes();
            AssemblyTypes.AddRange(executingTypes);

            //获取 当前应用程序的主程序集（当前如果是类库则返回null）
            var entryTypes = Assembly.GetEntryAssembly()?.GetExportedTypes();
            if (entryTypes != null && entryTypes.Length > 0)
            { AssemblyTypes.AddRange(entryTypes); }

            //添加传入的程序集 的公共类型
            AssemblyTypes.AddRange(assemblies?.SelectMany(a => a.GetExportedTypes()) ?? new List<Type>());

            var doMainAssemblies = AppDomain.CurrentDomain.GetAssemblies().Where(x => x.FullName.StartsWith("XYS.", StringComparison.InvariantCultureIgnoreCase)).ToList();
            if (doMainAssemblies.Count > 0)
            {
                AssemblyTypes.AddRange(doMainAssemblies.SelectMany(a => a.GetExportedTypes()));
            }

            //自动识别 香橼树 的程序集
            var xysFiles = Directory.GetFiles(".", "XYS.*.dll");
            if (xysFiles != null && xysFiles.Length > 0)
            {
                var assembliesForFile = new List<Assembly>();
                foreach (var xysFile in xysFiles)
                {
                    var name = Path.GetFileNameWithoutExtension(xysFile);
                    try
                    {
                        assembliesForFile.Add(Assembly.Load(name));
                    }
                    catch { }
                }
                if (assembliesForFile.Count > 0)
                {
                    AssemblyTypes.AddRange(assembliesForFile.SelectMany(a => a.GetExportedTypes()));
                }
            }

            //去重
            AssemblyTypes = AssemblyTypes.DistinctBy(t => t.FullName).ToList();
            return AssemblyTypes;
        }

        /// <summary>
        /// 获取程序集版本号
        /// </summary>
        /// <param name="assemby"></param>
        /// <returns></returns>
        public static string GetAssemblyVersion(Assembly assemby)
        {
            if (assemby != null)
            {
                var assembyString = assemby.ToString();
                if (!string.IsNullOrWhiteSpace(assembyString))
                {
                    int beginIndex = assembyString.IndexOf("Version=") + "Version=".Length;
                    if (beginIndex > 0)
                    {
                        int endIndex = assembyString.IndexOf(", ", beginIndex);
                        if (endIndex > 0)
                        {
                            return assembyString[beginIndex..endIndex];
                        }
                    }
                }
            }

            return null;
        }

    }
}
